<template>
    <div class="flex flex-col w-[312px] rounded-xl overflow-hidden border border-[#E4E7ED]">
        <div class="border-b h-[64px] bg-[#F4F4F4] px-2 py-4 flex-none">
            <input class="search-input rounded-full border px-4 py-[5px]" v-model="data.search" placeholder="搜索用户名">
        </div>
        <ol class="flex-1 overflow-y-auto">
            <li class="channel relative flex py-3 px-2 gap-2" :class="{selected: channel.id === data.selectedChannel?.id}" v-for="channel in channels" :key="channel.id" @click="select(channel)">
                <img class="h-[48px] w-[48px] rounded-full flex-none" :src="channel.avatar" alt="">
                <div class="flex flex-col justify-center flex-1 overflow-hidden">
                    <div class="flex justify-between gap-2">
                        <div class="title">{{ channel.nickName }}</div>
                        <div class="detail">{{ timeDes(channel.modifyTime) }}</div>
                    </div>
                    <div class="flex justify-between gap-2">
                        <div class="detail">{{ channel.content.content }}</div>
                        <div v-if="channel.unReadCount" class="badge-dot mt-2"></div>
                    </div>
                </div>
            </li>
            <li v-if="!data.channels.length">
                <img class="mx-auto block mt-[64px]" src="./assets/empty.svg" alt="">
                <div class="empty-text -mt-4">暂无消息</div>
            </li>
        </ol>
    </div>
</template>

<script setup lang="ts">
import { Loader } from 'src/framework/network/Loader';
import { computed, reactive, onDeactivated, onActivated } from 'vue';
import dayjs from 'dayjs'
import * as api from './api';

const data = reactive({
    search: '',
    channels: [] as api.Channel[],
    selectedChannel: null as api.Channel | null
})

const channels = computed(() => {
    if (data.search === '') {
        return data.channels
    } else {
        return data.channels.filter(c => c.nickName.includes(data.search))
    }
})

const emit = defineEmits<{
    (event: 'select', value: api.Channel): void
}>()

const loader = reactive(new Loader(api.fetchChannels))
let lastRefreshTime = 0
let canceller: ReturnType<typeof Promise.setInterval> | undefined

async function reload() {
    data.channels = await loader.load()
    lastRefreshTime = (new Date()).getTime()
    canceller = Promise.setInterval(refresh,5000)
}

async function refresh() {
    const newChannles = await loader.load({ t: lastRefreshTime })
    data.channels.forEach(oldc => {
        const newc = newChannles.find(newc => newc.id === oldc.id)
        if (newc) {
            Object.assign(oldc, newc)
        }
    })
    data.channels.sort((a,b) => b.modifyTime.localeCompare(a.modifyTime))
    lastRefreshTime = (new Date()).getTime()
}
onActivated(reload)
onDeactivated(() => canceller?.cancel())


function select(channel: api.Channel) {
    data.selectedChannel = channel
    channel.unReadCount = 0
    emit('select', channel)
}

function timeDes(timeStr: string) {
    const nSecsAgo = dayjs().diff(timeStr) / 1000
    if (nSecsAgo < 60) {
        return '刚刚'
    } else if (nSecsAgo < 3600) {
        return `${ Math.floor(nSecsAgo / 60) }分钟前`
    } else if (nSecsAgo < 86400) {
        return `${ Math.floor(nSecsAgo / 3600) }小时前`
    } else if (nSecsAgo < 86400 * 7) {
        return `${ Math.floor(nSecsAgo / 86400) }天前`
    } else {
        return timeStr.substring(0,10)
    }
}

</script>

<style scoped>
.title {
    font-family: 'Noto Sans SC';
    font-style: normal;
    font-weight: 500;
    font-size: 14px;
    line-height: 22px;

    display: flex;
    align-items: center;
    font-feature-settings: 'tnum' on, 'lnum' on;

    color: #414448;
    flex: none;
}

.detail {
    font-family: 'Noto Sans SC';
    font-style: normal;
    font-weight: 400;
    font-size: 12px;
    line-height: 22px;

    align-items: center;
    font-feature-settings: 'tnum' on, 'lnum' on;

    color: #C0C4CC;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
}

.badge-dot {
    width: 8px;
    height: 8px;
    background: #EE7171;
    border-radius: 24px;
    flex: none;
}

.empty-text {
    font-family: 'Noto Sans SC';
    font-style: normal;
    font-weight: 400;
    font-size: 14px;
    line-height: 22px;
    /* identical to box height, or 157% */

    font-feature-settings: 'tnum' on, 'lnum' on;

    color: #D8D8D8;
    text-align: center;
}

.search-input {
    font-family: 'Noto Sans SC';
    font-style: normal;
    font-weight: 400;
    font-size: 14px;
    line-height: 22px;
    font-feature-settings: 'tnum' on, 'lnum' on;
    color: #414448;
    width: 100%;

    background: #FFFFFF;
    border: 1px solid #E4E7ED;
}

.search-input::placeholder {
    color: #C0C4CC;
}
.search-bar:after, .channel:after {
    content: '';
    position: absolute;
    background-color: #E4E7ED;
    height: 1px;
    bottom: 0;
    left: 0;
    right: 0;
}
.channel {
    transition: background 250ms;
}
.channel.selected {
    background: #F8F8F8;
    transition-duration: 0ms;
}
</style>